/*!	 dialog_spritesheetparam.cpp
**	 Implementation for the SpriteSheetParam Dialog
**
**	Copyright (c) 2015 Denis Zdorovtsov
**
**	This package is free software; you can redistribute it and/or
**	modify it under the terms of the GNU General Public License as
**	published by the Free Software Foundation; either version 2 of
**	the License, or (at your option) any later version.
**
**	This package is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**	General Public License for more details.
**
*/

#include <cmath>

#include <synfig/general.h>

#include <gtkmm/grid.h>
#include <gui/localization.h>
#include "dialogs/dialog_spritesheetparam.h"

namespace studio
{

Dialog_SpriteSheetParam::Dialog_SpriteSheetParam(Gtk::Window &parent):
    Dialog_TargetParam(parent, _("Sprite sheet parameters")),
    frame_count(0)
{
    // Checkbox
    check_button = Gtk::manage(new Gtk::CheckButton(_("Add into an existing file."), true));

    // Offset X
    Gtk::Label* offset_x_label(manage(new Gtk::Label(_("Offset X:"))));
    offset_x_label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
    offset_x_box = Gtk::manage(new Gtk::SpinButton(Gtk::Adjustment::create(0.0, 0.0, 10000.0)));

    // Offset Y
    Gtk::Label* offset_y_label(manage(new Gtk::Label(_("Offset Y:"))));
    offset_y_label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
    offset_y_box = Gtk::manage(new Gtk::SpinButton(Gtk::Adjustment::create(0.0, 0.0, 10000.0)));

    // Dirrection
    Gtk::Label* direction_label(manage(new Gtk::Label(_("Direction:"))));
    direction_label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
    direction_box = Gtk::manage(new Gtk::ComboBoxText());
    direction_box->append("horizontal");
    direction_box->append("vertical");
    direction_box->set_active(0);
    direction_box->signal_changed().connect(sigc::mem_fun(*this, &Dialog_SpriteSheetParam::on_dir_change));

    // Row count
    Gtk::Label* rows_label(manage(new Gtk::Label(_("Rows:"))));
    rows_label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
    rows_box = Gtk::manage(new Gtk::SpinButton(Gtk::Adjustment::create(0.0, 1.0, 1000.0)));
    rows_box->signal_value_changed().connect(sigc::mem_fun(*this, &Dialog_SpriteSheetParam::on_rows_change));

    // Column count
    Gtk::Label* columns_label(manage(new Gtk::Label(_("Columns:"))));
    columns_label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
    columns_box = Gtk::manage(new Gtk::SpinButton(Gtk::Adjustment::create(0.0, 1.0, 1000.0)));
    columns_box->signal_value_changed().connect(sigc::mem_fun(*this, &Dialog_SpriteSheetParam::on_cols_change));

    // Grid
    Gtk::Grid* grid = Gtk::manage(new Gtk::Grid());
    grid->attach(*check_button, 0, 0, 2, 1);
    grid->attach(*offset_x_label, 0, 1, 1, 1);
    grid->attach(*offset_x_box, 1, 1, 1, 1);
    grid->attach(*offset_y_label, 2, 1, 1, 1);
    grid->attach(*offset_y_box, 3, 1, 1, 1);
    grid->attach(*direction_label, 0, 2, 2, 1);
    grid->attach(*direction_box, 1, 2, 3, 1);
    grid->attach(*rows_label, 0, 3, 1, 1);
    grid->attach(*rows_box, 1, 3, 1, 1);
    grid->attach(*columns_label, 2, 3, 1, 1);
    grid->attach(*columns_box, 3, 3, 1, 1);
    grid->set_row_spacing(4);
    grid->set_column_spacing(2);
    grid->set_border_width(8);
    grid->show_all();

    get_content_area()->pack_start(*grid, true, true, 3);
    get_content_area()->show_all();
}

Dialog_SpriteSheetParam::~Dialog_SpriteSheetParam()
{
}

void
Dialog_SpriteSheetParam::init()
{
    frame_count = get_desc().get_frame_end() - get_desc().get_frame_start() + 1;

    offset_x_box->set_value(get_tparam().offset_x);
    offset_y_box->set_value(get_tparam().offset_y);
    rows_box->set_value(get_tparam().rows);
    columns_box->set_value(get_tparam().columns);
    direction_box->set_active(get_tparam().dir);
    check_button->set_active(get_tparam().append);
    on_dir_change(); // Update boxes
}

void
Dialog_SpriteSheetParam::on_dir_change()
{
    rows_box->set_sensitive(direction_box->get_active_row_number() == 1);
    rows_box->set_value(direction_box->get_active_row_number() == 1 ? frame_count : 1);
    columns_box->set_sensitive(direction_box->get_active_row_number() == 0);
    columns_box->set_value(direction_box->get_active_row_number() == 0 ? frame_count : 1);
}

void
Dialog_SpriteSheetParam::on_rows_change()
{
    static bool flag = false;

    if (direction_box->get_active_row_number() == 0) {
        return;
    }

    if ((flag = !flag)) {
        columns_box->set_value(ceil((double)frame_count / rows_box->get_value()));
    }
}

void
Dialog_SpriteSheetParam::on_cols_change()
{
    static bool flag = false;

    if (direction_box->get_active_row_number() == 1) {
        return;
    }

    if ((flag = !flag)) {
        rows_box->set_value(ceil((double)frame_count / columns_box->get_value()));
    }
}

void
Dialog_SpriteSheetParam::write_tparam(synfig::TargetParam & tparam_)
{
    tparam_.offset_x = offset_x_box->get_value();
    tparam_.offset_y = offset_y_box->get_value();
    tparam_.rows = rows_box->get_value();
    tparam_.columns = columns_box->get_value();
    tparam_.dir = (synfig::TargetParam::Direction)direction_box->get_active_row_number();
    tparam_.append = check_button->get_active();
}

}